package mapbox;

import android.content.Context;
import android.graphics.Point;
import android.support.annotation.NonNull;
import android.util.Log;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.CoordinateConverter;
import com.amap.api.location.DPoint;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.services.android.telemetry.MapboxTelemetry;
import com.mapbox.services.android.telemetry.http.TelemetryClient;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;

import library.Library;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Response;

/**
 * Created by apple on 2017/3/31.
 */

public class MapUtils {

    private static final String MAPBOX_KEY = "pk.eyJ1IjoiaW5mb2hvbGQiLCJhIjoiY2oxMjNwbjJhMDVidDJ3cnRleTZrODhuNCJ9.j1bH49oxLTcEmnnuy6-wdw";

    public static void init(@NonNull Context context) {
        Mapbox.getInstance(context, MAPBOX_KEY);
        try {
            Field fieldTelemetryClient = MapboxTelemetry.class.getDeclaredField("client");
            fieldTelemetryClient.setAccessible(true);
            TelemetryClient telemetryClient = (TelemetryClient) fieldTelemetryClient.get(MapboxTelemetry.getInstance());
            telemetryClient.setEventsEndpoint("http://localhost");
            Field fieldOkHttpClient = TelemetryClient.class.getDeclaredField("client");
            fieldOkHttpClient.setAccessible(true);
            OkHttpClient okHttpClient = (OkHttpClient) fieldOkHttpClient.get(telemetryClient);
            fieldOkHttpClient.set(telemetryClient, replaceClient(context, okHttpClient));


            Class HTTPRequestClass = Class.forName("com.mapbox.mapboxsdk.http.HTTPRequest");
            Field mClient = HTTPRequestClass.getDeclaredField("mClient");
            mClient.setAccessible(true);
            OkHttpClient client = (OkHttpClient) mClient.get(null);
            mClient.set(null, replaceClient(context, client));
        } catch (Exception e) {
            Log.e("MapUtils", e.getMessage(), e);
        }
    }

    public static OkHttpClient replaceClient(Context context, OkHttpClient client) {
        return replaceClient(context, client, "MapCache", 64 * 1024 * 1024, true, 60 * 60 * 24 * 15);
    }

    public static OkHttpClient replaceClient(Context context,
                                             OkHttpClient client,
                                             String file,
                                             int maxSize,
                                             boolean force,
                                             int maxAge) {
        OkHttpClient.Builder builder = client.newBuilder();
        File cache = new File(context.getObbDir(), file);
        cache.mkdirs();
        builder.addInterceptor(new CacheInterceptor(force, maxAge));
        builder.cache(new Cache(cache, maxSize));
        return builder.build();
    }


    public static LatLng lonLat2Mercator(LatLng latLng) {
        double x = latLng.getLongitude() * 20037508.34 / 180;
        double y = Math.log(Math.tan((90 + latLng.getLatitude()) * Math.PI / 360)) / (Math.PI / 180);
        y = y * 20037508.34 / 180;
        LatLng point=new LatLng();
        point.setLongitude(x);
        point.setLatitude(y);
        return point;
    }

    public static LatLng mercator2LatLng(double X, double Y) {

        double x = X / 20037508.34 * 180;
        double y = Y / 20037508.34 * 180;
        y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
        LatLng lonLat = new LatLng(y, x);
        return lonLat;
    }

    public static AMapLocation fromGpsToAmap(double latitude, double longitude) {
        AMapLocation aMapLocation = new AMapLocation((String) null);
        CoordinateConverter converter = new CoordinateConverter(Library.getContext());
        converter.from(CoordinateConverter.CoordType.GPS);
        try {
            converter.coord(new DPoint(latitude, longitude));
            DPoint desLatLng = converter.convert();
            aMapLocation.setLatitude(desLatLng.getLatitude());
            aMapLocation.setLongitude(desLatLng.getLongitude());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return aMapLocation;
    }

    public static LatLng getLatLonFromWGS84(double latitude, double longitude) {

        AMapLocation mapLocation = fromGpsToAmap(latitude, longitude);

        return new LatLng(mapLocation.getLatitude(), mapLocation.getLongitude());
    }


    private static final class CacheInterceptor implements Interceptor {
        private final int maxAge;
        private final boolean force;

        private CacheInterceptor(boolean force, int maxAge) {
            this.maxAge = maxAge;
            this.force = force;
        }


        @Override
        public Response intercept(Chain chain) throws IOException {
            Response origin = chain.proceed(chain.request());
            return origin.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public,max-age=" + maxAge + (force ? ",only-if-cached" : ""))
                    .build();
        }

    }
}
